

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import ch.zhaw.swp1.model.message.Message;

/**
 * Keeps track of the unsent messages and iterates over them in a separate thread.
 * @author Daniel Tiefenauer
 */
public class MessageHandler {
	
	private static Vector<Message> messages = new Vector<Message>();
	private static Thread thread = null;
	private static boolean shutdown = false;
	
	
	/************************************************************************************/
	/* Methods
	/************************************************************************************/
	/**
	 * Add single new message to the list
	 * @param message a new Message
	 */
	public synchronized static void addMessage(Message message){
		if (thread == null){
			thread = new Thread(new MessageRunnable());
			thread.start();
		}
		messages.add(message);
	}
	
	/**
	 * Add a list of messages to existing messages. Messages are added one at a time.
	 * @param messageList a List of messages
	 */
	public synchronized static void addMessageList(List<Message> messageList){
		Iterator<Message> it = messageList.iterator();
		while(it.hasNext()){
			messages.add(it.next());
		}
	}
	
	/**
	 * Add a vector of messages to existing messages. Messages are added one at a time.
	 * @param messageList a Vector of messages
	 */
	public synchronized static void addMessageList(Vector<Message> messageList){
		Iterator<Message> it = messageList.iterator();
		while(it.hasNext()){
			messages.add(it.next());
		}
	}
	
	/**
	 * Check if there are unsent messages in the queue
	 * @return true if there are messages still to be sent in the queue, false if queue is empty
	 */
	public static boolean hasMessages(){
		return !messages.isEmpty();
	}

	/**
	 * Start polling thread over messages (if not already running
	 */
	public static void start(){
		if (thread == null){
			thread = new Thread(new MessageRunnable());
			thread.start();
			System.out.println("Message handler Thread started");
		}
		else {
			System.out.println("Message handleris already running");
		}
	}
	
	/**
	 * Soft stop polling thread. If there are still messages in the queue, the thread continues
	 * running until all messages are sent.
	 */
	public static void stop(){
		if(!shutdown && messages.size()>0){
			System.out.println("Can't shutdown because there are still messages left to be sent.");
			System.out.println("Use shutdown() to force shutdown.");
			System.out.println("Waiting for messages to be sent...");
			while(messages.size()>0){
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}			
				System.err.println("Still " + messages.size() + " messages left...");
			}
			shutdown = true;
		}
	}
	
	/**
	 * USE WITH CAUION: Force Shutdown thread. Unsent messages will be lost.
	 */
	public static void shutdown(){
		shutdown = true;
	}
	
	/************************************************************************************/
	/* Getter/Setter
	/************************************************************************************/	
	public static Vector<Message> getMessages(){
		return messages;
	}
	public static void setMessages(Vector<Message> messageList){
		messages = messageList;
	}


	/**
	 * Inner Class to iterate over messages
	 * @author Daniel Tiefenauer
	 */
	static final class MessageRunnable implements Runnable {
		@Override
		public void run() {
			while (!shutdown) {
				for (int i = 0; i < messages.size(); i++) {
					synchronized(messages){
						Message message = messages.get(i);
						if (System.currentTimeMillis() >= message.getSendTime()) {
							message.send();
							messages.remove(i);
						}
					}
				}
			}

		}

	}
}
